#ifndef __BITMAP__H__
#define __BITMAP__H__

#include "format.h"

#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

struct bitmap_base
{
	uint16_t align_bit;
	uint16_t file_flag;
	uint32_t file_size;
	uint32_t reserved;
	uint32_t offset;
};

struct bitmap_head
{
	struct bitmap_base base;
	uint32_t info_size;
	uint32_t width;
	uint32_t height;
	uint16_t planes;
	uint16_t bit_per_pixel;
	uint32_t compression;
	uint32_t data_size;
	uint32_t h_resolution;
	uint32_t v_resolution;
	uint32_t colors;
	uint32_t important_colors;
};

struct bitmap_line
{
	unsigned int line_id;
	uint8_t *line_data;
	struct bitmap_line *prov;
	struct bitmap_line *next;
};

typedef struct bitmap_class
{
	uint32_t line_length;
	void **p_memdup;

	struct bitmap_head head;
	struct bitmap_line *first_line;

	uint8_t *(*getline_byid)(struct bitmap_class *, unsigned int);
	void (*padline)(struct bitmap_class *, unsigned char *, uint32_t);
	int (*dump)(struct bitmap_class *);
	int (*memfree)(struct bitmap_class *, unsigned char **);
	int (*memdup)(struct bitmap_class *, unsigned char **, uint32_t *);
	int (*tofile)(struct bitmap_class *, char *);
	int (*mem_merge)(struct bitmap_class *, rgb24_class *);
	void (*release)(struct bitmap_class **);
} bitmap_class;

static inline void *get_head_addr(struct bitmap_class *bmp)
{
	return (uint8_t *)(&bmp->head) + sizeof(bmp->head.base.align_bit);
}

static inline uint32_t get_head_size(struct bitmap_class *bmp)
{
	return sizeof(bmp->head) - sizeof(bmp->head.base.align_bit);
}

static inline uint32_t get_line_length(uint32_t width)
{
	return ((width * 3) + 3) & (~3);
}

extern struct bitmap_class *init_bmp(uint32_t, uint32_t);

#ifdef __cplusplus
}
#endif

#endif